С каждым классом пороженным от CObject связывается структура CRuntimeClass, в которой находится информация о классе. Её можно использовать для получения информации об объекте.
struct CRuntimeClass
{
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema;
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;
void Store(CArchive& ar) const;
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);
CRuntimeClass* m_pNextClass;
};
Все эти атрибуты легко получить. Пример:
// TestP.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "afxwin.h"
#include "iostream.h"
void main()
{
CFile cf;
CRuntimeClass *cr;
cr=cf.GetRuntimeClass();
cout << cr->m_lpszClassName << " " << cr->m_nObjectSize
<< " " << cr->m_wSchema << endl;
}
CObject* (PASCAL* m_pfnCreateObject)(); - если поддерживается динамическое создание, то тут хранится указатель на конструктор по умолчанию, иначе NULL.
Определение _AFXDLL позволяет по разному описать класс в зависимости от того с какой версией MFC вы работаете, т.е. динамической или статической.
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)(); - только в динамической версии, указатель на структуру базового класса. Для статической используется CRuntimeClass* m_pBaseClass;.
CObject* CreateObject(); - создание объекта, если он поддерживает динамическое создание.
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; - проверка является ли класс производным.
Функции Store() и Load осуществляют чтение и сохранение класса в файловый поток.